﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SMS.Entities.BaseClasses;
using SMS.Common.Silverlight;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;

namespace SMS.ViewModel.Admin
{
    public class ViewModel_UserRegistration:BaseNotify, INotifyDataErrorInfo
    {
        Model.AuthenticationModel authenticationModel=null;
        string _mode = string.Empty;
        public ViewModel_UserRegistration()
        {
            InitializeCommand();
            IntializeModel();            
            this.errors = new Dictionary<string, List<string>>();
        }

        private void IntializeModel()
        {
            authenticationModel = new Model.AuthenticationModel();
            ApplicationUserObject = new Entities.Admin.ApplicationUser();
        }

        private void InitializeCommand()
        {
            SaveCommand = new DelegateCommand(Save, null);
            CancelCommand = new DelegateCommand(Cancel);
        }

        #region Method.

        public void Save(object param)
        {
            #region "For Validations"
            var allErrors = new Dictionary<string, List<string>>();

            foreach (var err in errors)
            {
                allErrors.Add(err.Key, err.Value);
            }
            foreach (var prvError in allErrors)
            {
                RemoveErrorFromProperty(prvError.Key, null, true);
            }

            errors.Clear();

            this.ValidationResults = new ObservableCollection<ValidationResult>();

            bool isValid = Validator.TryValidateObject(this, new ValidationContext(this, null, null), this.ValidationResults, true);
            if (!isValid)
            {

                foreach (ValidationResult vr in ValidationResults)
                {
                    string[] msgs = { vr.ErrorMessage };
                    AddErrorToProperty(((string[])(vr.MemberNames))[0], msgs, true);
                }
                return;
            }
            #endregion

            if (Password != RePassword)
            {
                ErrorMessage="Password must be match";
                return;
            }
            if (SelectedBranch == null)
            {
                ErrorMessage = "Please select branch";
                return;
            }
            if (SalesManObject == null)
            {
                ErrorMessage = "Please select Sales Man";
                return;
            }
            UserMessage = "New User Saving....";

            ApplicationUserObject.SalesMan = new Entities.SalesManDetail();
            ApplicationUserObject.SalesMan.SalesMan_ID= SalesManObject.SalesMan_ID;
            ApplicationUserObject.LastLogin = DateTime.Now;
            ApplicationUserObject.FirstName = FirstName;
            ApplicationUserObject.LastName = LastName;
            ApplicationUserObject.UserName = UserName;
            ApplicationUserObject.Password = Password;
            ApplicationUserObject.Email = Email;
            ApplicationUserObject.Role = 1;
            ApplicationUserObject.Branch = new Entities.Master.Branch();
            ApplicationUserObject.Branch.Branch_ID = SelectedBranch.Branch_ID;
            ApplicationUserObject.DisplayName = ApplicationUserObject.FirstName + " " + ApplicationUserObject.LastName;
            ApplicationUserObject.PicturePath = ApplicationUserObject.FirstName + ".jpg";

            authenticationModel.SaveNewUserCompleted += new Action<Entities.Admin.ApplicationUser>(authenticationModel_SaveNewUserCompleted);
            authenticationModel.SaveNewUser(App.LoggedinUserName, ApplicationUserObject); 
        }

        void authenticationModel_SaveNewUserCompleted(Entities.Admin.ApplicationUser obj)
        {
            if (obj != null)
            {
                UserMessage = "New User Saved Successfully.";
            }
            else
            {
                ErrorMessage = "Error Occured!!";
            }
        }

        private void Cancel(object param)
        {
            App.GoBack();
        }

        #endregion

        #region Properties

        public ChildWindow ChildWindow { get; set; }

        private string _firstName;
        [Required(ErrorMessage = "First Name is required")]
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; OnPropertyChanged("FirstName"); }
        }

        private string _lastName;
        [Required(ErrorMessage = "Last Name is required")]
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; OnPropertyChanged("LastName"); }
        }

        private string _UserName;
        [Required(ErrorMessage = "User Name is required")]
        public string UserName
        {
            get { return _UserName; }
            set { _UserName = value; OnPropertyChanged("UserName"); }
        }

        private string _password;
        [Required(ErrorMessage = "Password is required")]
        public string Password
        {
            get { return _password; }
            set { _password = value; OnPropertyChanged("Password"); }
        }

        private string _confirmPassword;
        [Required(ErrorMessage = "Confirm Password is required")]
        public string RePassword
        {
            get { return _confirmPassword; }
            set { _confirmPassword = value; OnPropertyChanged("RePassword"); }
        }

        private SMS.Entities.Master.Branch _SelectedBranch;
       // [Required(ErrorMessage = "Please select Branch")]
        public SMS.Entities.Master.Branch SelectedBranch
        {
            get { return _SelectedBranch; }
            set { _SelectedBranch = value; OnPropertyChanged("SelectedBranch"); }
        }        

        private string _email;
        [Required(ErrorMessage = "Email is required")]
        public string Email
        {
            get { return _email; }
            set { _email = value; OnPropertyChanged("Email"); }
        }

        private bool  _isActive;

        public bool  IsActive
        {
            get { return _isActive; }
            set { _isActive = value; OnPropertyChanged("IsActive"); }
        }
        

        private SMS.Entities.SalesManDetail _salesManObject;
        //[Required(ErrorMessage = "Please select sales man")]
        public SMS.Entities.SalesManDetail SalesManObject
        {
            get { return _salesManObject; }
            set
            { 
                _salesManObject = value; 
                OnPropertyChanged("SalesManObject"); 
            }
        }

        private SMS.Entities.Admin.ApplicationUser _applicationUserObject;

        public SMS.Entities.Admin.ApplicationUser ApplicationUserObject
        {
            get { return _applicationUserObject; }
            set { _applicationUserObject = value; OnPropertyChanged("ApplicationUserObject"); }
        }

       
        #endregion

        #region DelegateCommand

        public ICommand SaveCommand { get; set; }
        public ICommand CancelCommand { get; set; }

        #endregion

        #region "INotifyDataErrorInfohh members implementation"

        ObservableCollection<ValidationResult> validationResults;
        public ObservableCollection<ValidationResult> ValidationResults
        {
            get
            {
                return this.validationResults;
            }
            set
            {
                this.validationResults = value;
                this.OnPropertyChanged("ValidationResults");
            }
        }

        private readonly Dictionary<string, List<string>> errors;

        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

        public IEnumerable GetErrors(string propertyName)
        {
            if ((!this.errors.ContainsKey(propertyName)) || string.IsNullOrEmpty(propertyName)) return this.errors;

            return this.errors[propertyName];
        }

        public bool HasErrors
        {
            get { return this.errors.Count > 0; }
        }

        public void Clear()
        {
            this.errors.Clear();
        }

        public void RemoveErrorFromProperty(string propertyName, string errorMessage = null, bool notifyErrorschanged = false)
        {
            if (!this.errors.ContainsKey(propertyName)) return;

            this.RemoveErrorFromPropertyIfErrorAlreadyExist(propertyName);

            if (notifyErrorschanged) this.NotifyErrorsChanged(propertyName);
        }

        private void RemoveErrorFromPropertyIfErrorAlreadyExist(string propertyName)
        {
            if (!this.errors.ContainsKey(propertyName)) return;

            this.errors[propertyName].Clear();
            if (this.errors[propertyName].Count == 0) this.errors.Remove(propertyName);
        }

        private void NotifyErrorsChanged(string propertyName)
        {
            if (this.ErrorsChanged != null)
                this.ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
        }

        public void AddErrorToProperty(string propertyName, string[] errorMessage, bool notifyErrorschanged = false)
        {
            this.RemoveErrorFromPropertyIfErrorAlreadyExist(propertyName);

            if (!this.errors.ContainsKey(propertyName)) this.errors.Add(propertyName, new List<string>());

            foreach (var message in errorMessage)
            {
                this.errors[propertyName].Add(message);
            }

            if (notifyErrorschanged) this.NotifyErrorsChanged(propertyName);
        }
        #endregion
    }
}
